use crate::vm::VirtualMachine;
use std::collections::HashSet;


/// 调试器结构体，用于调试虚拟机器
pub struct Debugger {
    vm: VirtualMachine,
    breakpoints: HashSet<usize>,
}

impl Debugger {
    /// 创建一个新的调试器实例
    pub fn new(vm: VirtualMachine) -> Self {
        Self {
            vm,
            breakpoints: HashSet::new(),
        }
    }

    /// 添加断点
    pub fn add_breakpoint(&mut self, address: usize) {
        self.breakpoints.insert(address);
    }

    /// 移除断点
    pub fn remove_breakpoint(&mut self, address: usize) {
        self.breakpoints.remove(&address);
    }

    /// 检查指定地址是否有断点
    pub fn has_breakpoint(&self, address: usize) -> bool {
        self.breakpoints.contains(&address)
    }

    /// 显示调用栈
    pub fn show_stack(&self) {
        if self.vm.get_stack().is_empty() {
            println!("  Stack is empty");
            return;
        }
        
        for (i, value) in self.vm.get_stack().iter().rev().enumerate() {
            println!("  #{:2}: {:?}", i, value);
        }
    }

    /// 显示变量信息
    pub fn show_variables(&self) {
        if self.vm.get_global_variables().is_empty() {
            println!("  No variables available");
            return;
        }
        
        println!("Global Variables:");
        for (name, value) in self.vm.get_global_variables() {
            println!("  {}: {:?}", name, value);
        }
    }

    /// 显示帮助信息
    pub fn show_help(&self) {
        println!("\nDebugger Commands:");
        println!("  continue (c)       - Continue execution");
        println!("  step (s)           - Step to next instruction");
        println!("  quit (q)           - Quit debugger");
        println!("  breakpoints (b)    - List breakpoints");
        println!("  stack (bt)         - Show stack contents");
        println!("  vars (locals)      - Show variables");
        println!("  help (h, ?)        - Show this help message");
    }

    /// 列出所有断点
    pub fn list_breakpoints(&self) {
        if self.breakpoints.is_empty() {
            println!("No breakpoints set");
            return;
        }
        
        let mut breakpoints: Vec<_> = self.breakpoints.iter().collect();
        breakpoints.sort();
        
        println!("Breakpoints:");
        for &address in breakpoints {
            println!("  {}", address);
        }
    }
}

/// 调试命令处理辅助函数
pub fn handle_debug_command(vm: VirtualMachine, command: &str) {
    let debugger = Debugger::new(vm);
    
    match command {
        "help" | "h" | "?" => debugger.show_help(),
        "breakpoints" | "b" => debugger.list_breakpoints(),
        "stack" | "bt" => debugger.show_stack(),
        "vars" | "locals" => debugger.show_variables(),
        _ => {
            println!("Unknown debug command: {}", command);
            debugger.show_help();
        }
    }
}
